<?php

class Helper_Head
{
    /**
     * @var array
     */
    protected $_vars = array();

    /**
     * constructor
     */
    public function __construct($config)
    {
        $this -> _config = $config;
    }

    /**
     * @param string $name
     * @param mixed $default
     * @return mixed
     */
    public function get_config($key, $default = null)
    {
        return isset($this -> _config[$key]) ? $this -> _config[$key] : $default;
    }

    /**
     * @param string $name
     * @return array
     */
    public function get($name)
    {
        return isset($this -> _vars[$name]) ? $this -> _vars[$name] : array();
    }

    /**
     * @param array $options
     * @return
     */
    public function set_config($key, $value)
    {
        $this -> _config[$key] = $value;
        return $this;
    }

    /**
     * get html from current tile
     * @return
     */
    public function get_html_from_title()
    {
        return sprintf('<title>%s</title>', implode($this -> get_config('title-separate', '-'), $this -> get('title')));
    }

    /**
     * flatten meta to html
     * @return string
     */
    public function get_html_from_meta()
    {
        $xhtml = array();

        foreach ($this->get('meta') as $meta)
        {
            $xhtml[] = '<meta ' . $this -> __flat($meta) . '/>';
        }
        return implode(PHP_EOL, $xhtml);
    }

    /**
     * flatten keyword to html
     * @return string
     */
    public function get_html_from_keyword()
    {
        return '<meta name="keyword" content="' . implode(', ', $this -> get('keyword')) . '"/>';
    }

    /**
     * flatten description to html
     * @return string
     */
    public function get_html_from_description()
    {
        return '<meta name="description" content="' . implode(', ', $this -> get('description')) . '"/>';
    }

    /**
     * flatten link to html
     * @return string
     */
    public function get_html_from_link()
    {
        $xhtml = array();

        foreach ($this->get('Link') as $value)
        {
            $xhtml[] = '<link ' . $this -> __flat($value) . '/>';
        }
        return implode(PHP_EOL, $xhtml);
    }

    /**
     * flatten css link to html
     * @return string
     */
    public function get_html_from_css_link()
    {
        $xhtml = array();

        foreach ($this->get('css_link') as $value)
        {
            $xhtml[] = '<link ' . $this -> __flat($value) . '/>';
        }
        return implode(PHP_EOL, $xhtml);
    }

    /**
     * flatten js link to html
     * @return string
     */
    public function get_html_from_js_link()
    {
        $xhtml = array();
        foreach ($this->get('js_link') as $value)
        {
            $xhtml[] = '<script ' . $this -> __flat($value) . '></script>';
        }
        return implode(PHP_EOL, $xhtml);
    }

    /**
     * get base href tags
     * @return string
     */
    public function get_html_from_base()
    {
        return '<base href="http://namnv.younetco.com/agis3/"/>';
    }

    /**
     * flatten opengrap to meta, it is helpful for social sites to know what is
     * this
     * site
     * @return string
     */
    public function get_html_from_opengraph()
    {
        return '';
    }

    /**
     * @param string $name
     * @return bool
     */
    public function is_empty($name)
    {
        return !isset($this -> _vars[$name]) || empty($this -> _vars[$name]);
    }

    /**
     * match action
     * @param string $name
     * @param string $option
     * @param string $default
     */
    protected function __empty($name, $option, $default = '')
    {

        $value = $this -> get_config($option, $default = '');

        if (isset($this -> _vars[$name]) && !empty($this -> _vars[$name]))
        {
            $this -> process($this -> get_config($option . '-option', ' append'), $name, $value);
        }
        else
        {
            $this -> process('set', $name, $value);
        }
        return $this;
    }

    public function add_meta($value)
    {
        $this -> _vars['meta'][] = $value;
        return $this;
    }

    /**
     * @return string
     */
    public function __toString()
    {
        /**
         * process some thing else as content or not of page.
         */
        $this -> add_meta(array(
            'http-equiv' => 'content-type',
            'content' => 'text/html; charset=utf-8'
        )) -> add_meta(array(
            'http-equiv' => 'content-language',
            'content' => $this -> get_config('content-language', 'en-us')
        )) -> add_meta(array(
            'name' => 'owner',
            'content' => $this -> get_config('owner')
        )) -> add_meta(array(
            'name' => 'author',
            'content' => $this -> get_config('author')
        )) -> add_meta(array(
            'name' => 'generator',
            'content' => $this -> get_config('generator')
        )) -> add_link(array(
            'rel' => 'shortcut icon',
            'type' => 'image/x-icon',
            'href' => 'http://namnv.younetco.com/nuo2/favicon.ico'
        )) -> __empty('Title', 'title', 'untitled name') -> __empty('Keyword', 'keyword', '') -> __empty('Description', 'description', '');

        $theme = 'admin';

        $this 
        -> prepend_css_link('/nuo2/static/minify/index.php?g=require.css&b=nuo2') 
        -> prepend_css_link('/nuo2/static/' . $theme . '/styles/main.css') 
        -> prepend_js_link('/nuo2/static/minify/index.php?g=require.js&b=nuo2') 
        -> prepend_js_link('/nuo2/static/minify/index.php?g=main.js&b=nuo2'); ;

        /**
         * @var array
         */
        $allows = array(
            'base',
            'link',
            'css_link',
            'meta',
            'keyword',
            'description',
            'title',
            'headScript',
            'css',
            'js_link',
            'script'
        );

        /**
         * @var array
         */
        $xhtml = array();

        foreach ($allows as $allow)
        {
            if (method_exists($this, $method = 'get_html_from_' . $allow) && ($html = $this -> {$method}()) != '')
            {
                $xhtml[] = $html;
            }
        }
        return implode(PHP_EOL, $xhtml);
    }

    public function correct_css_link($value)
    {
        if (is_string($value))
        {
            $value = array('href' => $value);
        }
        return array_merge(array(
            'type' => 'text/css',
            'rel' => 'stylesheet',
            'media' => 'all',
            'charset' => 'utf-8'
        ), $value);
    }

    public function correct_js_link($value)
    {
        if (is_string($value))
        {
            $value = array('src' => $value);
        }
        return array_merge(array(
            'type' => 'text/javascript',
            'charset' => 'utf-8'
        ), $value);
    }

    public function __call($name, $args)
    {
        return $this -> process($name, $name, isset($args[0]) ? $args[0] : null);
    }

    /**
     * placement
     * @param string $name
     * @param string/array $value
     * @return mixed
     */
    protected function process($action, $name, $value = null)
    {
        /**
         * @var string $type
         */
        $pos = strpos($action, '_');
        $array = explode('_', $action);

        $action = substr($action, 0, $pos);

        $key = substr($action, $pos + 1);

        if (!isset($this -> _vars[$key]))
        {
            $this -> _vars[$key] = array();
        }

        if (method_exists($this, $method = 'correct' . $key))
        {
            $value = $this -> {$method}($value);
        }

        switch($action)
        {
            case 'append' :
            case 'add' :
                $this -> _vars[$key][] = $value;
                return $this;
            case 'prepend' :
                $this -> _vars[$key] = array_reverse($this -> _vars[$key]);
                $this -> _vars[$key][] = $value;
                $this -> _vars[$key] = array_reverse($this -> _vars[$key]);
                return $this;
            case 'clear' :
                $this -> _vars[$key] = array();
                return $this;
            case 'set' :
                $this -> _vars[$key] = array($value);
            case 'has' :
                return isset($this -> _vars[$key]) && !empty($this -> _vars[$key]);
            case 'none' :
        }
        return $this;
    }

    protected function __flat($array)
    {
        $xhtml = array();
        foreach ($array as $key => $value)
        {
            $xhtml[] = sprintf('%s="%s"', $key, $value);
        }
        return implode(' ', $xhtml);
    }

}
